import React, { useEffect, useState, useRef } from "react";
import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import * as THREE from "three";
import {  Select } from "antd";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import "./Ai.css";

const ThreeScene: React.FC = () => {
  const [modelUrl] = useState("/modules/over.glb");
  const [index, setIndex] = useState(0);
  const [selectedAction, setSelectedAction] = useState<THREE.AnimationClip[]>([]);
  const dragbox = useRef<HTMLDivElement | null>(null);
  const [currentEmotion, setCurrentEmotion] = useState('neutral');
  const [isSpeaking, setIsSpeaking] = useState(false);
  const mixerRef = useRef<THREE.AnimationMixer | null>(null);
  const modelRef = useRef<THREE.Group | null>(null);
  const [model, setModel] = useState<THREE.Group | null>(null);
  const morphTargetDictionaryRef = useRef<{ [key: string]: number }>({});
  const morphTargetInfluencesRef = useRef<number[]>([]);

  // 动作映射表
  const actionMap = {
    dance: 0,      // 跳舞
    walk: 1,       // 跺脚
    crying: 2,     // 哭泣
    break: 3       // 无语一下
  };

  // 表情映射表
  const emotionMap = {
    happy: { mouthOpen: 0.5, mouthSmile: 0.8, eyesHappy: 0.7 },
    sad: { mouthFrown: 0.6, eyesSad: 0.8 },
    angry: { mouthFrown: 0.4, eyesAngry: 0.7 },
    surprised: { mouthOpen: 0.7, eyesWide: 0.8 },
    neutral: { mouthNeutral: 0.5, eyesNeutral: 0.5 }
  };

  // 处理语音指令事件
  useEffect(() => {
    const handleAnimationChange = (event: CustomEvent) => {
      const { action } = event.detail;
      if (action && actionMap[action as keyof typeof actionMap] !== undefined) {
        setIndex(actionMap[action as keyof typeof actionMap]);
      }
    };

    window.addEventListener('changeAnimation', handleAnimationChange as EventListener);
    return () => {
      window.removeEventListener('changeAnimation', handleAnimationChange as EventListener);
    };
  }, []);

  // 修改handleChange函数
  const handleChange = (value: string) => {
    switch(value) {
      case "走一下":
        setIndex(0);
        break;
      case "跺脚":
        setIndex(1);
        break;
      case "哭一下":
        setIndex(2);
        break;
      case "无语一下":
        setIndex(3);
        break;
    }
  };

  // 更新表情变形目标
  const updateMorphTargets = (emotionValues: { [key: string]: number }) => {
    if (!morphTargetDictionaryRef.current || !morphTargetInfluencesRef.current) return;

    Object.entries(emotionValues).forEach(([key, value]) => {
      const index = morphTargetDictionaryRef.current[key];
      if (index !== undefined) {
        morphTargetInfluencesRef.current[index] = value;
      }
    });
  };

  // 处理语音动画
  const handleSpeech = (text: string) => {
    setIsSpeaking(true);
    
    // 简单的口型动画
    const mouthAnimation = () => {
      if (!isSpeaking) return;
      
      const openAmount = Math.random() * 0.5 + 0.2; // 随机口型开合度
      updateMorphTargets({ mouthOpen: openAmount });
      
      setTimeout(() => {
        updateMorphTargets({ mouthOpen: 0 });
        if (isSpeaking) {
          setTimeout(mouthAnimation, 100);
        }
      }, 100);
    };

    mouthAnimation();

    // 语音结束后重置
    setTimeout(() => {
      setIsSpeaking(false);
      const currentEmotionValues = emotionMap[currentEmotion as keyof typeof emotionMap];
      if (currentEmotionValues) {
        updateMorphTargets(currentEmotionValues);
      }
    }, text.length * 200);
  };

  // 拖拽逻辑保持不变
  useEffect(() => {
    const handleMouseDown = (e: MouseEvent) => {
      if (!dragbox.current) return;
      const x = e.pageX - dragbox.current.offsetLeft;
      const y = e.pageY - dragbox.current.offsetTop;

      const handleMouseMove = (e: MouseEvent) => {
        if (!dragbox.current) return;
        dragbox.current.style.left = `${e.pageX - x}px`;
        dragbox.current.style.top = `${e.pageY - y}px`;
      };

      const handleMouseUp = () => {
        document.removeEventListener("mousemove", handleMouseMove);
        document.removeEventListener("mouseup", handleMouseUp);
      };

      document.addEventListener("mousemove", handleMouseMove);
      document.addEventListener("mouseup", handleMouseUp);
    };

    if (dragbox.current) {
      dragbox.current.addEventListener("mousedown", handleMouseDown);
    }

    return () => {
      if (dragbox.current) {
        dragbox.current.removeEventListener("mousedown", handleMouseDown);
      }
    };
  }, [dragbox]);

  // 模型加载和动画逻辑
  useEffect(() => {
    const loader = new GLTFLoader();
    const mixer = new THREE.AnimationMixer(new THREE.Object3D());
    mixerRef.current = mixer;

    loader.load(
      modelUrl,
      (gltf) => {
        const loadedModel = gltf.scene;
        setSelectedAction(gltf.animations);
        modelRef.current = loadedModel;

        // 获取变形目标字典
        loadedModel.traverse((child) => {
          if (child instanceof THREE.Mesh && child.morphTargetDictionary) {
            morphTargetDictionaryRef.current = child.morphTargetDictionary;
            morphTargetInfluencesRef.current = child.morphTargetInfluences || [];
          }
        });

        // 设置模型位置
        const bbox = new THREE.Box3().setFromObject(loadedModel);
        const height = bbox.max.y - bbox.min.y;
        loadedModel.position.z = height / 2;
        setModel(loadedModel);

        // 设置动画
        if (mixerRef.current && gltf.animations[index]) {
          const clip = gltf.animations[index];
          // 确保动画轨道名称与模型骨骼名称匹配
          const action = mixerRef.current.clipAction(clip, loadedModel);
          action.timeScale = 0.8;
          action.clampWhenFinished = false;
          action.play();
        }

        // 动画循环
        const animate = () => {
          requestAnimationFrame(animate);
          if (mixerRef.current) {
            mixerRef.current.update(0.016);
          }
        };
        animate();
      },
      undefined,
      (error) => {
        console.error("Error loading model:", error);
      }
    );

    return () => {
      if (mixerRef.current) {
        mixerRef.current.stopAllAction();
      }
    };
  }, [modelUrl, index]);

  return (
    <div className="aaa">
      <Canvas>
        <ambientLight intensity={3} />
        <directionalLight position={[10, 10, 10]} intensity={3} />
        {model && (
          <>
            <primitive object={model} />
            <OrbitControls />
          </>
        )}
      </Canvas>

      <div className="button-containe" ref={dragbox}>
        <Select
          defaultValue="切换动作"
          style={{ width: 220 }}
          onChange={handleChange}
          options={[
            { value: "走一下" },
            { value: "跺脚" },
            { value: "哭一下" },
            { value: "无语一下" }
          ]}
        />
      </div>
    </div>
  );
};

export default ThreeScene;
